Skip to content

Wrap PySerial inside busio.UART for Linux platforms - #1106

Merged
makermelissa merged 2 commits into
adafruit:mainfrom
makermelissa-ai-assistant:wrap-pyserial-uart-linux
Apr 17, 2026
Merged

Wrap PySerial inside busio.UART for Linux platforms#1106
makermelissa merged 2 commits into
adafruit:mainfrom
makermelissa-ai-assistant:wrap-pyserial-uart-linux

Conversation

@makermelissa-ai-assistant

Copy link
Copy Markdown
Contributor

Summary

Fixes #332.

Instead of raising RuntimeError on embedded Linux, busio.UART now wraps PySerial via a new generic_linux UART backend. This lets CircuitPython UART code run unchanged on Linux / SBC boards (Raspberry Pi, BeagleBone, etc.).

Changes

New file: src/adafruit_blinka/microcontroller/generic_linux/uart.py

  • PySerial-backed UART with full CircuitPython API
  • Resolves port IDs to /dev/ device paths automatically (/dev/serial0, /dev/ttyS0, /dev/ttyAMA0, etc.)
  • Supports string device paths for direct use
  • Methods: read, readinto, readline, write, deinit, reset_input_buffer
  • Properties: baudrate, in_waiting, timeout

Updated: src/busio.py

  • UART.__init__ now imports generic_linux.uart when detector.board.any_embedded_linux is true (instead of raising RuntimeError)
  • Follows the same pattern used by busio.I2C and busio.SPI for Linux support
  • Added missing CircuitPython API members:
    • timeout property (getter/setter)
    • __enter__() / __exit__() context manager support
    • reset_input_buffer() method
    • baudrate as a proper property (getter/setter) instead of a plain attribute
  • Fixed timeout default from 1000 (stale milliseconds value) to 1 (seconds), matching CircuitPython 4.0+ convention
  • Improved deinit() to call the backend's deinit() when available

Usage

import board
import busio

# Works on Linux now — no more RuntimeError!
uart = busio.UART(board.TX, board.RX, baudrate=115200)
data = uart.read(32)

# Context manager support
with busio.UART(board.TX, board.RX, baudrate=9600) as uart:
    uart.write(b'hello')

Notes

  • PySerial (pyserial) must be installed but is not added to install_requires — it's already commonly available on Linux SBC setups and is used elsewhere in the project (e.g. RP2040 U2IF)
  • The port ID mapping uses uartPorts from the board's pin definitions (same as I2C uses i2cPorts)

Fixes adafruit#332.

Instead of raising RuntimeError on embedded Linux, busio.UART now uses a
new generic_linux UART backend that wraps PySerial.  This lets
CircuitPython UART code run unchanged on Linux / SBC boards.

Changes:
- Add src/adafruit_blinka/microcontroller/generic_linux/uart.py
  PySerial-backed UART with full CircuitPython API (read, readinto,
  readline, write, deinit, baudrate, in_waiting, timeout,
  reset_input_buffer).
- Update busio.UART to import the generic_linux backend when
  detector.board.any_embedded_linux is true, matching the pattern
  used by busio.I2C and busio.SPI.
- Add missing CircuitPython API members to busio.UART:
  - timeout property (getter/setter)
  - __enter__() / __exit__() context manager
  - reset_input_buffer()
  - baudrate as a proper property (getter/setter)
- Fix timeout default from 1000 (stale milliseconds) to 1 (seconds),
  matching CircuitPython 4.0+ convention.

@makermelissa makermelissa left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good.

@makermelissa
makermelissa merged commit 2551cd5 into adafruit:main Apr 17, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Possibly wrap PySerial inside UART for linux systems

2 participants